package com.openess.bigsearch.engine.search;

import com.openess.bigsearch.engine.BTree.util.Arrays;
import com.openess.bigsearch.engine.analyzer.Analyzer;
import com.openess.bigsearch.engine.document.Field;
import com.openess.bigsearch.engine.index.Token;

/**
 * 这个类用于包装查询语句，在内部进行分词
 * 
 * @author TuTu
 * 
 */
public class Query {
	/**
	 * 域名
	 */
	private String fieldName;
	/**
	 * 查询语句分词后，保存在数组中
	 */
	private String[] queryList;
	/**
	 * 查询向量的模长
	 */
	private double norm;

	/**
	 * 构造函数，按域搜索
	 * 
	 * @param fileName
	 *            域名
	 * @param query
	 *            查询语句
	 * @param an
	 *            使用的解析器
	 */
	public Query(String fileName, String query, Analyzer an) {
		this.fieldName = fileName;
		Token<String, Integer>[] temp = an.parse(0, query);
		this.queryList = filter(temp);
	}

	/**
	 * 构造方法，全文搜索
	 * 
	 * @param query
	 * @param an
	 */
	public Query(String query, Analyzer an) {
		this("", query, an);
	}

	/**
	 * 过滤掉查询词当中的重复项，以免在计算最终分数值时，重复计算同一个查询词
	 * 
	 * @param list
	 * @return
	 */
	private String[] filter(Token<String, Integer>[] list) {
		String[] array = new String[list.length];
		int i = 0;
		for (Token<String, Integer> t : list)
			array[i++] = t.getKey();
		return Arrays.repeatFilter(array);
	}

	/**
	 * 检测查询语句分词后，是否是单独一个词项
	 * 
	 * @return 如果分词结果为空，那么也返回false
	 */
	public boolean isSingly() {
		if (queryList == null) {
			return false;
		}
		return queryList.length == 1;
	}

	/**
	 * 得到query对象中，经过解析后，查询分词的数量
	 * 
	 * @return 如果queryList为空，返回0
	 */
	public int length() {
		if (queryList == null) {
			return 0;
		}
		return queryList.length;
	}

	/**
	 * 否是按域进行搜索
	 * 
	 * @return
	 */
	public boolean isField() {
		return fieldName.length() != 0;
	}

	/**
	 * 判断是否为关键域，如果是，并返回其下标
	 * 
	 * @return
	 */
	public int isMainField() {
		String[] list = Field.MAINFIELD;
		for (int i = 0; i < list.length; i++)
			if (fieldName.equals(list[i]))
				return i;
		return -1;
	}

	public final String getFileName() {
		return fieldName;
	}

	public final double getNorm() {
		return norm;
	}

	public final String[] getQueryList() {
		return queryList;
	}

	public final void setNorm(double norm) {
		this.norm = norm;
	}
}
